package com.lin.maker.meta;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.lin.maker.meta.Enum.FileGenerateTypeEnum;
import com.lin.maker.meta.Enum.FileTypeEnum;
import com.lin.maker.meta.Enum.ModelTypeEnum;

import java.io.File;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;

public class MetaValidtor {
    public static final String doValid(Meta meta){
        //检验meta数据的基本信息
        doValidBasicInformation(meta);
        //检验meta数据的文件相关信息
        doValidFileInformation(meta);
        //检验meta数据的数据字段信息
        doValidDataInformation(meta);
        return null;
    }

    private static void doValidDataInformation(Meta meta) {
        Meta.ModelConfigDTO modelConfig = meta.getModelConfig();
        if (modelConfig == null) {
            return;
        }
        List<Meta.ModelConfigDTO.ModelInfo> models = modelConfig.getModels();
        if(CollUtil.isNotEmpty(models)){
            for (Meta.ModelConfigDTO.ModelInfo model : models) {
                String type = model.getType();
                String groupKey = model.getGroupKey();
                //有这个groupKey 说明是分组就不需要校验
                if(StrUtil.isNotBlank(groupKey)){
                    List<Meta.ModelConfigDTO.ModelInfo> modelsInfoList = model.getModels();
                    //如果我们想在字符串中插入一个双引号字符 "，必须使用转义字符 \ 来表示它，即 \"。
                    //所以，\"--%s\" 的意思是：生成的字符串将包括一个双引号包围的格式化字符串。例如，String.format("\"--%s\"", "name") 的结果是 "--name"，这个结果中包含了两个双引号。
                    // 换句话说你想在字符串中生成 "",就需要用到这个 \"
                    String collect = modelsInfoList.stream().map(modelInfo -> String.format("\"--%s\"", modelInfo.getFieldName())).collect(Collectors.joining(","));
                    model.setAllArgsStr(collect);
                    continue;
                }
                String fieldName = model.getFieldName();
                if(StrUtil.isBlank(fieldName)){
                    throw new MetaException("字段名不能为空");
                }
                if(StrUtil.isBlank(type)){
                    model.setType(ModelTypeEnum.STRING.getText());
                }
            }
        }
    }

    private static void doValidFileInformation(Meta meta) {
        Meta.FileConfigDTO fileConfig = meta.getFileConfig();
        if(fileConfig == null){
            throw new MetaException("文件配置不能为空");
        }
        String inputRootPath = fileConfig.getInputRootPath();
        String sourceRootPath = fileConfig.getSourceRootPath();
        // sourceRootPath 必填
        if(StrUtil.isBlank(sourceRootPath)){
            throw new MetaException("源码根路径不能为空");
        }
        // 如果没有inputRootPath ，默认是 source + sourceRootPath 的最后一个路径层级
        String defaultinputRootPath = "source/" +
                FileUtil.getLastPathEle(Paths.get(sourceRootPath)).getFileName().toString();
        if(StrUtil.isBlank(inputRootPath)){
            fileConfig.setInputRootPath(defaultinputRootPath);
        }
        String outputRootPath = fileConfig.getOutputRootPath();
        String defaultOutputRootPath = "generated";
        if(StrUtil.isBlank(outputRootPath)){
            fileConfig.setOutputRootPath(defaultOutputRootPath);
        }
        String fileConfigType = fileConfig.getType();
        if(StrUtil.isBlank(fileConfigType)){
            fileConfig.setType(FileTypeEnum.DIR.getText());
        }
        List<Meta.FileConfigDTO.FileInfo> files = fileConfig.getFiles();
        if(CollectionUtil.isEmpty(files)){
            return;
        }
        for (Meta.FileConfigDTO.FileInfo file : files) {
            String type = file.getType();
            if(FileTypeEnum.GROUP.getValue().equals(type)){
                continue;
            }
            String inputPath = file.getInputPath();
            // todo 我觉得可以直接读取defaultinputRootPath 下的对应包路径
            if(StrUtil.isBlank(inputPath)){
                throw new MetaException("输入路径不能为空");
            }
            String outputPath = file.getOutputPath();
            //输入路径默认是输出路径
            if(StrUtil.isBlank(outputPath)){
                file.setOutputPath(inputPath);
            }

            // 先判断有没有文件后缀 有文件后缀是file，否则是dir
            if(StrUtil.isBlank(type)){
                if(StrUtil.isBlank(FileUtil.getSuffix(new File(inputPath)))){
                    file.setType(FileTypeEnum.DIR.getText());
                }else {
                    file.setType(FileTypeEnum.FILE.getText());
                }
            }
            // 如果文件后缀是 .java 就是动态文件dynamic，否则就是静态
            String generateType = file.getGenerateType();
            if (StrUtil.isBlank(generateType)) {
                if (StrUtil.endWith(inputPath, ".ftl")){
                    file.setGenerateType(FileGenerateTypeEnum.DYNAMIC.getText());
                }else {
                    file.setGenerateType(FileGenerateTypeEnum.STATIC.getText());
                }
            }
        }
    }

    private static void doValidBasicInformation(Meta meta) {
        //检验meta数据的基本信息
        String name = StrUtil.blankToDefault(meta.getName(), "my-generator");
        String description = StrUtil.blankToDefault(meta.getDescription(), "代码生成器");
        String basePackage = StrUtil.blankToDefault(meta.getBasePackage(), "com.lin");
        String version = StrUtil.blankToDefault(meta.getVersion(), "1.0.0");
        String author = StrUtil.blankToDefault(meta.getAuthor(), "lin");
        String createTime = StrUtil.blankToDefault(meta.getCreateTime(), DateUtil.now());
        meta.setName(name);
        meta.setDescription(description);
        meta.setBasePackage(basePackage);
        meta.setVersion(version);
        meta.setAuthor(author);
        meta.setCreateTime(createTime);
    }
}
